﻿using System;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Xml;

namespace GateKeeper
{
    public static class Honeypot
    {
        private static Regex honeypotUrl = new Regex(GateKeeperModule.config.HoneyPotPath, RegexOptions.IgnoreCase);
        
        public static Boolean isHoneyPotVoilator(HttpContext current)
        {
            GateKeeperModule.log.Debug("Entering isHoneyPotVoilator");
            
            if (!honeypotUrl.IsMatch(current.Request.Url.AbsolutePath))
            {
                GateKeeperModule.log.Debug("Honeypot url path was not found in the request path");
                return false; 
            }

            if (GateKeeperModule.config.EnableHoneyPotLogging)
            {
                GateKeeperModule.log.Debug("Adding violator into HoneyPot log");
                AddHoneyPotEntry(current); 
            }

            // Add new entry in the ipaddress deny list
            if (GateKeeperModule.config.PersistHoneyPotDeny)
            {
                GateKeeperModule.log.Debug("Adding entry into IPAddress blacklist");
                //Utils.AddIPAddressEntry(XmlFileType.BlackList, current.Request.UserHostAddress, "HoneyPot violation");
                Utils.AddEntry(XmlFileType.BlackList, NodeType.ipaddress, current.Request.UserHostAddress, "HoneyPot violation");
            }

            // if NotifyAdmin is enabled then send an email
            if (GateKeeperModule.config.NotifyAdmin)
            { Smtp.SendNotification(current); }

            onViolation(current);
            GateKeeperModule.log.Debug("Leaving isHoneyPotVoilator");
            return true;
        }

        public static void AddHoneyPotEntry(HttpContext current)
        {
            XmlNode newNode = Utils.xmlHoneyPotList.CreateElement("entry");

            Utils.newXmlAttribute(newNode, "id", System.Guid.NewGuid().ToString("N"));
            Utils.newXmlAttribute(newNode, "date", DateTime.Now.ToString());
            Utils.newXmlAttribute(newNode, "ipaddress", current.Request.UserHostAddress.ToString());

            // Check of value empty, if so add string "empty"
            string userAgent = current.Request.UserAgent == null ? "Empty" : current.Request.UserAgent;
            Utils.newXmlAttribute(newNode, "useragent", userAgent);

            // Check of value empty, if so add string "empty"
            string referrer = HttpContext.Current.Request.UrlReferrer == null ? "Empty" : current.Request.UrlReferrer.AbsoluteUri;
            Utils.newXmlAttribute(newNode, "referrer", referrer);

            Utils.xmlHoneyPotList.SelectSingleNode("/gatekeeper/honeypot").AppendChild(newNode);
            Utils.SaveXMLFile(Utils.xmlHoneyPotList, XmlFileType.HoneyPotList);
            GateKeeperModule.log.InfoFormat("Added new HoneyPot violator : [{0}]", current.Request.UserHostAddress.ToString());

            // execute eventHandler
            onAddedEntry(current);
        }

        #region events
        public static event EventHandler<EventArgs> Violation;
        private static void onViolation(HttpContext current)
        {
            if (Violation != null)
            {
                GateKeeperModule.log.Debug("Executing Violation eventHandler");
                Violation(current, new EventArgs()); 
            }
        }
        
        public static event EventHandler<EventArgs> AddedEntry;
        private static void onAddedEntry(HttpContext current)
        {
            if (AddedEntry != null)
            {
                GateKeeperModule.log.Debug("Executing AddedEntry eventHandler");
                AddedEntry(current, new EventArgs()); 
            }
        }
        #endregion //events
    }
}
